home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / admin / linuxcon.000 / linuxcon / linuxconf-1.6 / netconf / datetime.c < prev    next >
C/C++ Source or Header  |  1996-06-30  |  7KB  |  265 lines

  1. #include <string.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <limits.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <time.h>
  8. #include "netconf.h"
  9. #include "internal.h"
  10. #include "../userconf/userconf.h"
  11. #include "../fstab/fstab.h"
  12. #include "netconf.m"
  13.  
  14. static const char DATETIME_P[]="datetime";
  15. static const char UNIVERSAL[]="universal";
  16. static const char NETDATE[]="netdate";
  17.  
  18. static NETCONF_HELP_FILE help_date ("datetime");
  19.  
  20. PUBLIC DATETIME::DATETIME()
  21. {
  22.     universal = linuxconf_getvalnum (DATETIME_P,UNIVERSAL,0);
  23.     netdate.setfrom (linuxconf_getval (DATETIME_P,NETDATE));
  24. }
  25.  
  26. PUBLIC void DATETIME::save()
  27. {
  28.     linuxconf_replace (DATETIME_P,UNIVERSAL,universal);
  29.     linuxconf_replace (DATETIME_P,NETDATE,netdate);
  30.     linuxconf_save();
  31. }
  32.  
  33. /*
  34.     Extract recursivly a directory, getting all files.
  35.     tbf will contain the path relative to a certain path (using
  36.     skip_prefix to strip the beginning).
  37. */
  38. static void datetime_zonelst (
  39.     int skip_prefix,
  40.     SSTRINGS &tbf,
  41.     const char *path)
  42. {
  43.     /* #Specification: netconf / datetime / zoneinfo / options
  44.         netconf finds the possible time zone available by listing
  45.         the content of the directory /usr/lib/zoneinfo. It does it
  46.         recursivly. It avoid symbolic links and  executable file.
  47.         The file "time.doc" is also removed explicitly since many
  48.         slackware do contain it.
  49.     */
  50.     int start = tbf.getnb();
  51.     dir_getlist (path,tbf);
  52.     int end = tbf.getnb();
  53.     for (int i=start; i<end; i++){
  54.         char fpath[PATH_MAX];
  55.         SSTRING *str = tbf.getitem(i);
  56.         const char *pt = str->get();
  57.         sprintf (fpath,"%s/%s",path,pt);
  58.         struct stat st;
  59.         char *replace = "";
  60.         if (lstat (fpath,&st)!=-1){
  61.             if (S_ISDIR(st.st_mode)){
  62.                 if (strcmp(pt,".")!=0
  63.                     && strcmp(pt,"..")!=0){
  64.                     datetime_zonelst (skip_prefix
  65.                         ,tbf,fpath);
  66.                 }
  67.             }else if(S_ISREG(st.st_mode)
  68.                 && strcmp(pt,"time.doc")!=0
  69.                 && ! (st.st_mode & 0100)){
  70.                 // As you see, we only collect regular
  71.                 // file. All others (directories, special
  72.                 // files or files that can't be stat will
  73.                 // be thrown away.
  74.                 replace = fpath+skip_prefix;
  75.             }
  76.         }
  77.         str->setfrom(replace);
  78.     }
  79. }
  80.  
  81. static void datetime_zonelst (FIELD_COMBO *comb)
  82. {
  83.     SSTRINGS tbf;
  84.     datetime_zonelst (strlen(USR_LIB_ZONEINFO)+1
  85.         ,tbf,USR_LIB_ZONEINFO);
  86.     tbf.sort();
  87.     int nb = tbf.getnb();
  88.     for (int i=0; i<nb; i++){
  89.         const char *pt = tbf.getitem(i)->get();
  90.         if (pt[0] != '\0') comb->addopt (pt);
  91.     }
  92. }
  93.  
  94. /*
  95.     Get or set the current zoneinfo by reading the symbolic link
  96.     /usr/lib/zoneinfo/localtime.
  97.  
  98.     
  99. */
  100. static void datetime_getsetcurzone(SSTRING &str)
  101. {
  102.     /* #Specification: netconf / datetime / zoneinfo / current
  103.         netconf finds out the current zone by looking at the
  104.         symbolic links /usr/lib/zoneinfo/localtime.
  105.  
  106.         It will follow this link up to five time.
  107.  
  108.         When setting the new time zone, it will also follows
  109.         the links and redo only the last one. The idea here is
  110.         that it support both strategy
  111.  
  112.         #
  113.         ln -sf /usr/lib/zoneinfo/country/value /usr/lib/zoneinfo/localtime
  114.         #
  115.  
  116.         and
  117.  
  118.         #
  119.         ln -sf /usr/lib/zoneinfo/country/value /var/lib/zoneinfo/localtime
  120.         ln -sf /var/lib/zoneinfo/localtime /usr/lib/zoneinfo/localtime
  121.         #
  122.  
  123.         The later being more "correct" fsstnd wise.
  124.     */
  125.     int iter = 0;
  126.     char path[PATH_MAX];
  127.     strcpy (path,USR_LIB_LOCALTIME);
  128.     while (iter < 5){
  129.         char buf[PATH_MAX];
  130.         int nb = readlink (path,buf,sizeof(buf)-1);
  131.         if (nb != -1){
  132.             buf[nb] = '\0';
  133.             struct stat st;
  134.             if (lstat(buf,&st)!=-1 && S_ISLNK(st.st_mode)){
  135.                 strcpy (path,buf);
  136.                 iter++;
  137.             }else{
  138.                 if (str.is_empty()){
  139.                     int skip = 0;
  140.                     static const char *prefix = USR_LIB_ZONEINFO "/";
  141.                     static int len = strlen(prefix);
  142.                     if (strncmp(prefix,buf,len) == 0) skip = len;
  143.                     str.setfrom (buf+skip);
  144.                 }else{
  145.                     unlink (path);
  146.                     const char *pt = str.get();
  147.                     if (pt[0] != '/'){
  148.                         sprintf (buf,"%s/%s",USR_LIB_ZONEINFO,pt);
  149.                         pt = buf;
  150.                     }
  151.                     symlink (pt,path);
  152.                 }
  153.                 break;
  154.             }
  155.         }
  156.     }
  157. }
  158. PUBLIC int DATETIME::edit ()
  159. {
  160.     int ret = -1;
  161.     if (perm_rootaccess(MSG_U(P_CHGDATE,"correct the date and time"))){
  162.         DIALOG dia;
  163.         SSTRING year,month,mday,hour,minutes,seconds;
  164.         {
  165.             time_t t;
  166.             time (&t);
  167.             struct tm *tmt = localtime (&t);
  168.             month.setfrom (tmt->tm_mon+1);
  169.             year.setfrom (tmt->tm_year);
  170.             mday.setfrom (tmt->tm_mday);
  171.             hour.setfrom (tmt->tm_hour);
  172.             minutes.setfrom (tmt->tm_min);
  173.             seconds.setfrom (tmt->tm_sec);
  174.         }
  175.         SSTRING zone;
  176.         datetime_getsetcurzone (zone);
  177.         FIELD_COMBO * comb = dia.newf_combo (MSG_U(F_ZONE,"zone"),zone);
  178.         datetime_zonelst (comb);
  179.         dia.newf_chk (MSG_U(F_STORECMOS,"Store date in CMOS"),universal
  180.             ,MSG_U(F_UNIVERSAL,"universal format(GMT)"));
  181.         dia.newf_str (MSG_U(F_GETDATE,"Get date from server(s)"),netdate);
  182.         dia.newf_title ("",MSG_U(T_TIME,"Time"));
  183.         dia.newf_str (MSG_U(F_HOUR,"Hour"),hour);
  184.         dia.newf_str (MSG_U(F_MINUTES,"Minutes"),minutes);
  185.         dia.newf_str (MSG_U(F_SECONDS,"Seconds"),seconds);
  186.         dia.newf_title ("",MSG_U(T_DATE,"Date"));
  187.         dia.newf_str (MSG_U(F_YEAR,"Year"),year);
  188.         dia.newf_str (MSG_U(F_MONTH,"Month"),month);
  189.         dia.newf_str (MSG_U(F_DAYOFMONTH,"Day of month"),mday);
  190.         if (dia.edit (MSG_U(T_DATETIME,"Workstation date & time")
  191.             ,MSG_U(I_DATETIME
  192.              ,"Fill this form to indicate how the workstation must\n"
  193.               "get its date and time\n")
  194.             ,help_date.getpath(),0) == MENU_ACCEPT){
  195.             datetime_getsetcurzone (zone);
  196.             struct tm tmt;
  197.             tmt.tm_hour = hour.getval();
  198.             tmt.tm_min = minutes.getval();
  199.             tmt.tm_sec = seconds.getval();
  200.             tmt.tm_year = year.getval();
  201.             if (tmt.tm_year > 1900) tmt.tm_year -= 1900;
  202.             tmt.tm_mon = month.getval()-1;
  203.             tmt.tm_mday = mday.getval();
  204.             tmt.tm_isdst = -1;
  205.             save();
  206.             if (netdate.is_empty()){
  207.                 time_t t = mktime (&tmt);
  208.                 stime (&t);
  209.             }else{
  210.                 getfromnet();
  211.             }
  212.             updatecmos();
  213.             ret = 0;
  214.         }
  215.     }
  216.     return ret;
  217. }
  218.  
  219. PUBLIC void DATETIME::updatecmos()
  220. {
  221.     netconf_system_if ("clock",universal ? "-w -u" : "-w");
  222. }
  223. /*
  224.     Get the date from CMOS
  225. */
  226. PUBLIC int DATETIME::getfromcmos()
  227. {
  228.     return netconf_system_if ("clock",universal ? "-s -u" : "-s");
  229. }
  230.  
  231. /*
  232.     Get the current date and time from servers on the net.
  233.     This will be done only if configured.
  234.  
  235.     Return -1 if any error.
  236.     Return 0 if ok or if it was not configured to do so.
  237. */
  238. PUBLIC int DATETIME::getfromnet()
  239. {
  240.     int ret = 0;
  241.     if (!netdate.is_empty()){
  242.         ret = netconf_system_if ("netdate",netdate.get());
  243.         if (ret == 0) updatecmos();
  244.     }
  245.     return ret;
  246. }
  247.  
  248. int datetime_getfromnet()
  249. {
  250.     DATETIME dt;
  251.     return dt.getfromnet();
  252. }
  253. int datetime_getfromcmos()
  254. {
  255.     DATETIME dt;
  256.     return dt.getfromcmos();
  257. }
  258.  
  259. int datetime_edit()
  260. {
  261.     DATETIME dt;
  262.     return dt.edit();
  263. }
  264.  
  265.